#include "start.h"
static int monster_bonus = 0;

// 数据库操作
sqlite3* db_open();
sqlite3_stmt* db_prepare(sqlite3* db, const char* sql);
void db_close(sqlite3* db);

// 数据库通用操作（模块化，减少冗余）
sqlite3* db_open() {
    sqlite3* db;
    if (sqlite3_open(DB_NAME, &db) != SQLITE_OK) {
        fprintf(stderr, "数据库打开失败: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return NULL;
    }
    return db;  
}

sqlite3_stmt* db_prepare(sqlite3* db, const char* sql) {
    if (!db || !sql) return NULL;
    sqlite3_stmt* stmt;
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
        fprintf(stderr, "SQL准备失败: %s\n", sqlite3_errmsg(db));
        return NULL;
    }
    return stmt;  
}

void db_close(sqlite3* db) {
    if (db) sqlite3_close(db);  
}


// 装备与英雄数据加载
int load_gear_database(Gear** gear_db, int* gear_count) {
    if (!gear_db || !gear_count) return SQLITE_ERROR;
    *gear_db = NULL;
    *gear_count = 0;
    sqlite3* db = db_open();
    if (!db) return SQLITE_ERROR;

    // 查询装备总数
    sqlite3_stmt* stmt = db_prepare(db, "SELECT COUNT(*) FROM gear");
    if (!stmt) {
        db_close(db);
        return SQLITE_ERROR;
    }
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        *gear_count = sqlite3_column_int(stmt, 0);
    } else {
        fprintf(stderr, "无法获取装备数量\n");
        sqlite3_finalize(stmt);
        db_close(db);
        return SQLITE_ERROR;
    }
    sqlite3_finalize(stmt);

    // 分配装备内存
    if (*gear_count <= 0) {
        fprintf(stderr, "无装备数据\n");
        db_close(db);
        return SQLITE_ERROR;
    }
    *gear_db = (Gear*)malloc(*gear_count * sizeof(Gear));
    if (!*gear_db) {
        fprintf(stderr, "装备内存分配失败\n");
        db_close(db);
        return SQLITE_ERROR;
    }

    // 加载装备详情
    stmt = db_prepare(db, "SELECT gear_id, gear_name, gear_effect, gear_slots_id FROM gear");
    if (!stmt) {
        free(*gear_db);
        *gear_db = NULL;
        db_close(db);
        return SQLITE_ERROR;
    }
    int index = 0;
    while (sqlite3_step(stmt) == SQLITE_ROW && index < *gear_count) {
        (*gear_db)[index].gear_id = sqlite3_column_int(stmt, 0);
        strncpy((*gear_db)[index].gear_name, (const char*)sqlite3_column_text(stmt, 1), MAX_GEAR_NAME - 1);
        (*gear_db)[index].gear_effect = sqlite3_column_int(stmt, 2);
        (*gear_db)[index].gear_slots_id = sqlite3_column_int(stmt, 3);
        index++;
    }
    sqlite3_finalize(stmt);
    db_close(db);
    return SQLITE_OK;
}

int load_hero(Hero* hero, const char* name) {
    if (!hero || !name) return SQLITE_ERROR;
    sqlite3* db = db_open();
    if (!db) return SQLITE_ERROR;

    sqlite3_stmt* stmt = db_prepare(db, 
        "SELECT hero_name, slots_head, slots_chest, slots_leg, slots_foot, slots_weapon FROM hero WHERE hero_name = ?");
    if (!stmt) {
        db_close(db);
        return SQLITE_ERROR;
    }
    sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC);

    int rc = SQLITE_ERROR;
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        strncpy(hero->name, (const char*)sqlite3_column_text(stmt, 0), MAX_HERO_NAME - 1);
        hero->slots_head = sqlite3_column_int(stmt, 1);
        hero->slots_chest = sqlite3_column_int(stmt, 2);
        hero->slots_leg = sqlite3_column_int(stmt, 3);
        hero->slots_foot = sqlite3_column_int(stmt, 4);
        hero->slots_weapon = sqlite3_column_int(stmt, 5);
        rc = SQLITE_OK;
    } else {
        fprintf(stderr, "未找到英雄：%s\n", name);
    }
    sqlite3_finalize(stmt);
    db_close(db);
    return rc;
}

int update_hero(const Hero* hero) {
    if (!hero) return SQLITE_ERROR;
    sqlite3* db = db_open();
    if (!db) return SQLITE_ERROR;

    sqlite3_stmt* stmt = db_prepare(db, 
        "UPDATE hero SET slots_head = ?, slots_chest = ?, slots_leg = ?, slots_foot = ?, slots_weapon = ? WHERE hero_name = ?");
    if (!stmt) {
        db_close(db);
        return SQLITE_ERROR;
    }
    sqlite3_bind_int(stmt, 1, hero->slots_head);
    sqlite3_bind_int(stmt, 2, hero->slots_chest);
    sqlite3_bind_int(stmt, 3, hero->slots_leg);
    sqlite3_bind_int(stmt, 4, hero->slots_foot);
    sqlite3_bind_int(stmt, 5, hero->slots_weapon);
    sqlite3_bind_text(stmt, 6, hero->name, -1, SQLITE_STATIC);

    int rc = (sqlite3_step(stmt) == SQLITE_DONE) ? SQLITE_OK : SQLITE_ERROR;
    sqlite3_finalize(stmt);
    db_close(db);
    return rc;
}


// 装备与战斗力同步逻辑
void sync_gear_value_to_battle(int* value_H) {
    if (!value_H) return;
    Hero hero;
    Gear* gear_db = NULL;
    int gear_count = 0;

    // 加载英雄和装备数据
    if (load_hero(&hero, "法外狂徒") != SQLITE_OK) {
        printf("加载英雄数据失败，装备加成无效\n");
        return;
    }
    if (load_gear_database(&gear_db, &gear_count) != SQLITE_OK) {
        printf("加载装备数据失败，装备加成无效\n");
        return;
    }

    // 计算装备总加成，同步战斗力（基础+装备+怪物收益）
    hero.gear_total = calculate_total_value(&hero, gear_db, gear_count);
    *value_H = INIT_BASE_VALUE + hero.gear_total + monster_bonus;
    printf("【战斗力同步】基础值(%d) + 装备加成(%d) + 怪物收益(%d) = %d\n",
           INIT_BASE_VALUE, hero.gear_total, monster_bonus, *value_H);

    // 释放内存
    free(gear_db);
}

int calculate_total_value(const Hero* hero, const Gear* gear_db, int gear_count) {
    if (!hero || !gear_db || gear_count <= 0) return 0;
    int total = 0;

    // 遍历装备匹配部位，累加效果
    for (int i = 0; i < gear_count; i++) {
        if (gear_db[i].gear_slots_id == 1 && hero->slots_head == gear_db[i].gear_id) {
            total += gear_db[i].gear_effect;
        } else if (gear_db[i].gear_slots_id == 2 && hero->slots_chest == gear_db[i].gear_id) {
            total += gear_db[i].gear_effect;
        } else if (gear_db[i].gear_slots_id == 3 && hero->slots_leg == gear_db[i].gear_id) {
            total += gear_db[i].gear_effect;
        } else if (gear_db[i].gear_slots_id == 4 && hero->slots_foot == gear_db[i].gear_id) {
            total += gear_db[i].gear_effect;
        } else if (gear_db[i].gear_slots_id == 5 && hero->slots_weapon == gear_db[i].gear_id) {
            total += gear_db[i].gear_effect;
        }
    }
    return total;
}

Gear get_random_gear(const Gear* gear_db, int gear_count) {
    Gear empty = {0};
    if (!gear_db || gear_count <= 0) return empty;

    static int seeded = 0;
    if (!seeded) {
        srand((unsigned int)time(NULL));
        seeded = 1;
    }
    return gear_db[rand() % gear_count];
}


// 装备更换逻辑（含战斗力同步）
void gear_change(int* value_H) {
    if (!value_H) return;
    Hero hero;
    Gear* gear_db = NULL;
    int gear_count = 0;

    // 加载数据
    if (load_hero(&hero, "法外狂徒") != SQLITE_OK) {
        printf("无法加载英雄数据\n");
        return;
    }
    if (load_gear_database(&gear_db, &gear_count) != SQLITE_OK) {
        printf("无法加载装备数据\n");
        return;
    }

    // 显示当前装备状态
    hero.gear_total = calculate_total_value(&hero, gear_db, gear_count);
    printf("\n【当前装备状态】\n");
    printf("英雄：%s | 装备总加成：%d | 当前战斗力：%d\n",
           hero.name, hero.gear_total, *value_H);
    printf("装备详情：\n");
    const char* slots[] = {"头部", "胸部", "腿部", "脚部", "武器"};
    int slot_ids[] = {hero.slots_head, hero.slots_chest, hero.slots_leg, hero.slots_foot, hero.slots_weapon};

    for (int i = 0; i < 5; i++) {
        printf("- %s：", slots[i]);
        int has_gear = 0;
        for (int j = 0; j < gear_count; j++) {
            if (gear_db[j].gear_id == slot_ids[i]) {
                printf("%s（+%d）\n", gear_db[j].gear_name, gear_db[j].gear_effect);
                has_gear = 1;
                break;
            }
        }
        if (!has_gear) printf("无\n");
    }

    // 随机掉落装备
    Gear dropped = get_random_gear(gear_db, gear_count);
    if (dropped.gear_id == 0) {
        printf("\n未掉落装备\n");
        free(gear_db);
        return;
    }
    printf("\n【随机掉落】%s（%s，效果+%d，ID：%d）\n",
           dropped.gear_name, get_slot_name(dropped.gear_slots_id),
           dropped.gear_effect, dropped.gear_id);

    // 选择是否装备
    char choice;
    printf("是否装备？(y/n)：");
    scanf(" %c", &choice);
    if (choice == 'y' || choice == 'Y') {
        // 更新对应部位装备
        switch (dropped.gear_slots_id) {
            case 1: hero.slots_head = dropped.gear_id; break;
            case 2: hero.slots_chest = dropped.gear_id; break;
            case 3: hero.slots_leg = dropped.gear_id; break;
            case 4: hero.slots_foot = dropped.gear_id; break;
            case 5: hero.slots_weapon = dropped.gear_id; break;
            default: printf("无效部位，装备失败\n"); break;
        }

        // 更新数据库和战斗力
        if (update_hero(&hero) == SQLITE_OK) {
            hero.gear_total = calculate_total_value(&hero, gear_db, gear_count);
            // 同步战斗力（保留怪物收益）
            *value_H = INIT_BASE_VALUE + hero.gear_total + monster_bonus;
            printf("装备成功！新装备总加成：%d | 新战斗力：%d\n", hero.gear_total, *value_H);
        } else {
            printf("装备成功，但数据库更新失败\n");
        }
    } else {
        printf("已放弃装备\n");
    }

    // 释放内存
    free(gear_db);
}


// 英雄面板展示
void show_hero_panel() {
    sqlite3* db = db_open();
    if (!db) return;

    sqlite3_stmt* stmt = db_prepare(db, 
        "SELECT h.hero_id, h.hero_name, "
        "g1.gear_name, g2.gear_name, g3.gear_name, g4.gear_name, g5.gear_name "
        "FROM hero h "
        "LEFT JOIN gear g1 ON h.slots_head = g1.gear_id "  // 正确：装备ID关联
        "LEFT JOIN gear g2 ON h.slots_chest = g2.gear_id "
        "LEFT JOIN gear g3 ON h.slots_leg = g3.gear_id "
        "LEFT JOIN gear g4 ON h.slots_foot = g4.gear_id "
        "LEFT JOIN gear g5 ON h.slots_weapon = g5.gear_id");
    if (!stmt) {
        db_close(db);
        return;
    }

    printf("\n【英雄面板】\n");
    HeroDisplay hero;
    int count = 0;
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        count++;
        hero.hero_id = sqlite3_column_int(stmt, 0);
        strncpy(hero.hero_name, (const char*)sqlite3_column_text(stmt, 1), MAX_HERO_NAME - 1);
        
        const char* head = (const char*)sqlite3_column_text(stmt, 2);
        strncpy(hero.head_gear, head ? head : "无", MAX_GEAR_NAME - 1);
        
        const char* chest = (const char*)sqlite3_column_text(stmt, 3);
        strncpy(hero.chest_gear, chest ? chest : "无", MAX_GEAR_NAME - 1);
        
        const char* leg = (const char*)sqlite3_column_text(stmt, 4);
        strncpy(hero.leg_gear, leg ? leg : "无", MAX_GEAR_NAME - 1);
        
        const char* foot = (const char*)sqlite3_column_text(stmt, 5);
        strncpy(hero.foot_gear, foot ? foot : "无", MAX_GEAR_NAME - 1);
        
        const char* weapon = (const char*)sqlite3_column_text(stmt, 6);
        strncpy(hero.weapon_gear, weapon ? weapon : "无", MAX_GEAR_NAME - 1);

        // 显示信息
        printf("ID：%d | 名称：%s\n", hero.hero_id, hero.hero_name);
        printf("装备：头部=%s，胸部=%s，腿部=%s，脚部=%s，武器=%s\n",
               hero.head_gear, hero.chest_gear, hero.leg_gear, hero.foot_gear, hero.weapon_gear);
        printf("----------------------------------------\n");
    }
    if (count == 0) printf("未查询到英雄数据\n");
    sqlite3_finalize(stmt);
    db_close(db);
}


// 怪物数据与战斗逻辑
char** get_monster_data() {
    char** data = (char**)malloc(MONSTER_DATA_COUNT * sizeof(char*));
    if (!data) return NULL;
    for (int i = 0; i < MONSTER_DATA_COUNT; i++) data[i] = NULL;

    sqlite3* db = db_open();
    if (!db) {
        free_monster_data(data);
        return NULL;
    }

    char** res = NULL;
    int nrow, ncol;
    char* errmsg = NULL;
    if (sqlite3_get_table(db, 
        "SELECT c_d.g_value FROM chd_value c_d JOIN g_value g_v ON c_d.value_g_id = g_v.g_value_id",
        &res, &nrow, &ncol, &errmsg) != SQLITE_OK) {
        fprintf(stderr, "怪物数据查询失败：%s\n", errmsg);
        sqlite3_free(errmsg);
        db_close(db);
        free_monster_data(data);
        return NULL;
    }

    if (nrow < MONSTER_DATA_COUNT) {
        fprintf(stderr, "怪物数据不足（需%d条，实际%d条）\n", MONSTER_DATA_COUNT, nrow);
        sqlite3_free_table(res);
        db_close(db);
        free_monster_data(data);
        return NULL;
    }

    // 复制数据（跳过表头）
    for (int i = 0; i < MONSTER_DATA_COUNT; i++) {
        data[i] = strdup(res[i + 1]);
    }
    sqlite3_free_table(res);
    db_close(db);
    return data;
}

void free_monster_data(char** data) {
    if (data) {
        for (int i = 0; i < MONSTER_DATA_COUNT; i++) {
            free(data[i]);
            data[i] = NULL;
        }
        free(data);
    }
}

int get_random_num(const int arr[], int length) {
    if (!arr || length <= 0) return -1;

    static int seeded = 0;
    if (!seeded) {
        srand((unsigned int)time(NULL));
        seeded = 1;
    }
    return arr[rand() % length];
}

void generate_monsters(int day, int* m1, int* m2) {
    if (!m1 || !m2 || day < 1 || day > 5) {
        *m1 = *m2 = -1;
        return;
    }

    // 加载怪物数据（数据库或默认）
    char** str_data = get_monster_data();
    int data[MONSTER_DATA_COUNT];
    if (str_data) {
        for (int i = 0; i < MONSTER_DATA_COUNT; i++) {
            data[i] = atoi(str_data[i]);
        }
        free_monster_data(str_data);
    } else {
        // 默认数据（每天递增）
        for (int i = 0; i < MONSTER_DATA_COUNT; i++) {
            data[i] = 10 + i * 5;
        }
    }

    // 按天分组（每天7条数据）
    int group_start = (day - 1) * 7;
    int group[7];
    for (int i = 0; i < 7; i++) {
        group[i] = data[group_start + i];
    }

    // 生成两个怪物
    *m1 = get_random_num(group, 7);
    *m2 = get_random_num(group, 6);  // 第二只从6条中选
}

int battle(int* day, int current_value) {
    if (!day || *day < 1 || *day > 5) return current_value;

    int m1, m2;
    generate_monsters(*day, &m1, &m2);
    printf("\n===== 第%d天战斗 =====\n", *day);
    printf("遭遇怪物：\n1. %s（战斗力：%d）\n2. %s（战斗力：%d）\n",
           "怪物1", m1, "怪物2", m2);

    // 选择怪物（容错输入）
    int choose;
    while (1) {
        printf("你的当前战斗力：%d，请选择挑战目标（1/2）：", current_value);
        if (scanf("%d", &choose) != 1) {
            printf("输入错误！请输入数字1或2\n");
            continue;
        }
        if (choose == 1 || choose == 2) break;
        printf("无效选择！请输入1或2\n");
    }

    // 战斗判断
    int target = (choose == 1) ? m1 : m2;
    if (current_value >= target) {
        monster_bonus += target;  // 累加怪物收益
        current_value += target;
        printf("胜利！获得%d战斗力，当前总战斗力：%d\n", target, current_value);
    } else {
        printf("失败！战斗力重置为初始状态\n");
        current_value = INIT_BASE_VALUE;  // 重置为基础值
        monster_bonus = 0;  // 清空怪物收益
        *day = 0;  // 重置天数（下一轮回到第1天）
    }
    return current_value;
}


// 修整菜单（含输入容错）
void choice_hero(int day, int* value_H) {
    if (day == 0 || !value_H) return;

    int n;
    do {
        printf("\n===== 第%d天修整 =====\n", day);
        printf("1. 查看英雄面板\n2. 查看掉落物\n3. 继续前进\n请选择：");
        if (scanf("%d", &n) != 1) {
            printf("输入错误！请输入数字1-3\n");
            n = 0;
            continue;
        }
        switch (n) {
            case 1:
                show_hero_panel();
                break;
            case 2:
                gear_change(value_H);  // 装备更换后直接更新战斗力
                break;
            case 3:
                printf("准备前往第%d天...\n", day + 1);
                sync_gear_value_to_battle(value_H);  // 出发前同步最新装备
                break;
            default:
                printf("无效选择！请输入1-3\n");
        }
    } while (n != 3);
}


// 工具函数
const char* get_slot_name(int slot_id) {
    switch (slot_id) {
        case 1: return "头部";
        case 2: return "胸部";
        case 3: return "腿部";
        case 4: return "脚部";
        case 5: return "武器";
        default: return "未知部位";
    }
}



/**
 * 通关后重置英雄状态：装备槽为空，血量(hero_value)为初始值
 */
int reset_hero_after_clear() {
    sqlite3* db = db_open();
    if (!db) return SQLITE_ERROR;

    // SQL：重置装备槽为NULL，hero_value设为初始值
    const char* sql = "UPDATE hero SET "
                      "slots_head = NULL, "
                      "slots_chest = NULL, "
                      "slots_leg = NULL, "
                      "slots_foot = NULL, "
                      "slots_weapon = NULL, "
                      "hero_value = 5 "  // 重置血量为初始值
                      "WHERE hero_name = '法外狂徒'";

    sqlite3_stmt* stmt = db_prepare(db, sql);
    if (!stmt) {
        fprintf(stderr, "重置英雄状态SQL准备失败: %s\n", sqlite3_errmsg(db));
        db_close(db);
        return SQLITE_ERROR;
    }

    int rc = (sqlite3_step(stmt) == SQLITE_DONE) ? SQLITE_OK : SQLITE_ERROR;
    if (rc == SQLITE_OK) {
        printf("\n【通关重置】英雄装备已清空，血量已恢复为初始值\n");
    } else {
        fprintf(stderr, "重置英雄状态失败: %s\n", sqlite3_errmsg(db));
    }

    sqlite3_finalize(stmt);
    db_close(db);
    return rc;
}

// ===== 游戏结束部分 =====
void start() {
    int day = 1;
    int value_H = INIT_BASE_VALUE;  // 初始战斗力（基础值）
    printf("===== 前进之路小游戏 =====\n");
    printf("规则：5天挑战，每天击败怪物提升战斗力（基础值+装备加成+怪物收益）\n");
    printf("失败则重置为初始状态（基础值5，无装备加成和怪物收益）\n\n");

    // 初始化：加载初始装备加成
    sync_gear_value_to_battle(&value_H);

    // 主循环（1-5天）
    while (day <= 5) {
        value_H = battle(&day, value_H);  // 战斗
        if (day == 0) {  // 若战斗失败（day被重置为0），重新从第1天开始
            day = 1;
            continue;
        }
        choice_hero(day, &value_H);       // 修整
        day++;  // 进入下一天
    }

    // 游戏结束
    printf("\n===== 游戏结束 =====\n");
    if (value_H > INIT_BASE_VALUE) {
        printf("恭喜完成5天挑战！最终战斗力：%d\n", value_H);
        
        // ===== 新增：通关后重置英雄装备和血量 =====
        if (reset_hero_after_clear() == SQLITE_OK) {
            printf("英雄状态已重置，下次游戏将从初始状态开始\n");
        } else {
            printf("英雄状态重置失败，请手动清理数据\n");
        }
    } else {
        printf("再接再厉！下次一定能通关～\n");
    }

}